// stores/chatStore.js

import { defineStore, storeToRefs } from 'pinia';
import { ref, computed } from 'vue';
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { useUserStore } from './user';

export const useChatStore = defineStore(
  'chat',
  () => {
    // 状态定义
    const messages = ref([]); // 存储所有完整消息
    // 假数据
    const currentUser = ref('User'); // 当前用户名称
    const streamingMessage = ref(null); // 正在接收的流式消息 一般是最后一条
    const isStreaming = ref(false); // 是否正在流式传输中
    const abortController = ref(null); // 用于中断请求的控制器
    const conversationId = ref(''); // 当前会话的id
    const { userInfo } = storeToRefs(useUserStore());

    // 计算属性：合并常规消息和当前流式消息
    const allMessages = computed(() => [...messages.value, ...(streamingMessage.value ? [streamingMessage.value] : [])]);
    // 对消息列表进一步处理 需要显示的信息
    const displayedMessages = computed(() => {
      // 1.判断是否显示时间 距离上次对话超过5分钟
      // 2.判断是否在思考中 如果已思考结束,则将content中的<details>标签删除
      return allMessages.value.map((msg, index) => {
        /** 处理时间 */
        // 第一条消息总是显示时间
        if (index === 0) return { ...msg, showTime: true };

        // 获取上一条消息
        const prevMsg = allMessages.value[index - 1];

        // 计算时间差（分钟）
        const timeDiff = (new Date(msg.timestamp) - new Date(prevMsg.timestamp)) / (1000 * 60);

        // 判断是否显示时间戳的条件：
        // 1. 当前消息是用户消息 且 2. 与上条消息间隔超过5分钟
        const shouldShowTime = msg.isUser && timeDiff > 5;

        return {
          ...msg,
          showTime: shouldShowTime,
          // 处理思考结束时的思考过程
          content: !msg.isStreaming ? msg.content.replace(/<details[\s\S]*?(<\/details>|$)/gi, '') : msg.content,
        };
      });
    });

    // 开始新的流式消息（初始化空消息）
    function startStreamingMessage() {
      streamingMessage.value = {
        id: 'streaming-' + Date.now(), // 唯一ID
        content: '', // 初始空内容
        isUser: false, // AI消息标记
        timestamp: Date.now(), // 时间戳
        isStreaming: true, // 流式标记
      };
      isStreaming.value = true;
      abortController.value = new AbortController(); // 创建中断控制器
    }
    // 更新流式消息
    function setStreamingMessage(data) {
      streamingMessage.value = {
        ...streamingMessage.value,
        conversation_id: data.conversation_id, // 会话ID
        timestamp: data.created_at,
      };
      // 存储当前会话的id 方便下次询问在此基础上进行
      conversationId.value = data.conversation_id;
    }

    // 向流式消息追加内容
    function appendToStream(content) {
      if (!streamingMessage.value) startStreamingMessage();
      streamingMessage.value.content += content;
    }

    // 结束流式传输（转为普通消息）
    function finalizeStreamingMessage() {
      if (streamingMessage.value) {
        messages.value.push({
          ...streamingMessage.value,
          isStreaming: false, // 移除流式标记
        });
        streamingMessage.value = null;
      }
      isStreaming.value = false;
      abortController.value = null;
    }

    // 中断当前流式传输
    function abortStreaming() {
      if (abortController.value) {
        abortController.value.abort();
      }
      finalizeStreamingMessage();
    }

    // 获取AI流式响应（核心方法）
    async function fetchAIResponse(queryInfo, teacherInfo) {
      startStreamingMessage(); // 初始化流式消息
      try {
        await fetchEventSource(import.meta.env.VITE_API_DEEPSEEK_URL + '/v1/chat-messages', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Authorization: 'Bearer ' + import.meta.env.VITE_API_SECRET_KEY,
          },
          body: JSON.stringify({
            inputs: {
              jsxm: teacherInfo || userInfo.value.userName,
              // jsxm: '超级管理员'
            },
            query: queryInfo,
            response_mode: 'streaming', //默认流式输出
            conversation_id: conversationId.value,
            user: userInfo.value.userId,
            // user: "1",
            files: [],
          }),
          signal: abortController.value?.signal, // 绑定中断信号

          // 连接建立时的回调
          onopen(response) {
            console.log('链接建立:', response);
            if (response.ok) {
              return;
            }
            throw new Error(`Server error: ${response.status}`);
          },

          // 收到消息时的处理
          onmessage(res) {
            // console.log(res)
            try {
              if (!res.data) return; // 过滤 ping 事件
              const data = JSON.parse(res.data);
              // console.log(data)
              if (data?.event == 'workflow_started') {
                // 开始标记
                console.log('连接开始');
                return setStreamingMessage(data);
              }

              // 支持两种常见API响应格式
              appendToStream(data.answer || '');
            } catch (e) {
              console.error('消息解析错误:', e);
            }
          },

          // 连接关闭
          onclose() {
            console.log('连接关闭');
            finalizeStreamingMessage();
          },

          // 错误处理
          onerror(err) {
            finalizeStreamingMessage();
            throw err; // 停止处理
          },
        });
      } catch (err) {
        console.log(err);
        if (err.name !== 'AbortError') {
          // 过滤用户主动中断
          // appendToStream(`\n\n抱歉，服务繁忙，请稍后再试。[${err.message}]`)
        }
        finalizeStreamingMessage();
      }
    }

    // 模拟AI流式响应（测试用）
    async function mockAIResponse(query) {
      startStreamingMessage();
      const signal = abortController.value.signal;

      try {
        // 模拟AI思考过程
        const mockResponses = [
          '让我思考一下...\n\n',
          '根据我的分析：\n',
          '1. 首先，',
          '这个问题涉及多个方面\n',
          '2. 其次，',
          '需要考虑上下文关系\n',
          '3. 最后，',
          '建议采取综合方案解决',
        ];

        const mockResponses2 = [
          ` ### 🐒 is-markdown 和 typing 结合使用 \n`,
          ` 这是一个 Markdown 示例。\n - 列表项 1 \n - 列表项 2 **粗体文本** 和 *斜体文本* \n`,
          ` \`\`\`javascript \n console.log('Hello, world!') \n \`\`\` `,
          ` 🐒 is-markdown 和 typing 结合使用 \n`,
          ` 🐒 is-markdown 和 typing 结合使用 \n`,
          ` 🐒 is-markdown 和 typing 结合使用 \n`,
        ];

        for (const chunk of mockResponses2) {
          // 检查是否被中断
          if (signal.aborted) {
            throw new Error('Stream aborted by user');
          }

          // 模拟网络延迟
          await new Promise(resolve => {
            const timer = setTimeout(() => {
              resolve();
            }, 300);

            // 如果中断，清除未执行的定时器
            signal.addEventListener('abort', () => {
              clearTimeout(timer);
            });
          });

          appendToStream(chunk);
        }
      } catch (err) {
        if (err.message === 'Stream aborted by user') {
          console.log('用户主动中断了AI思考');
        } else {
          console.error('模拟AI响应出错:', err);
        }
      } finally {
        finalizeStreamingMessage();
      }
    }

    // 添加普通消息 用户专用
    function addMessage(content, isUser = true) {
      messages.value.push({
        id: Date.now(), // 使用时间戳作为ID
        content,
        isUser,
        timestamp: Date.now(),
        isStreaming: false,
      });
    }

    // 清空所有消息
    function clearMessages() {
      abortStreaming(); // 先中断可能存在的流式请求
      messages.value = [];
      conversationId.value = '';
    }

    return {
      messages,
      currentUser,
      streamingMessage,
      isStreaming,
      allMessages,
      displayedMessages,
      conversationId,
      addMessage,
      clearMessages,
      fetchAIResponse,
      mockAIResponse,
      abortStreaming,
    };
  },
  { persist: true }
);
